/**
 * 发送聊天消息到后端模型
 */
async function sendChatMessageToBackendModel() {
	/**
	 * 获取用户输入并去除前后空格
	 */
	const userMessage = getUserMessage();
	// 检查消息是否为空或按钮是否禁用
	if (!userMessage || getInputButtonsDisabledState()) return;
	/**
	 * 添加用户消息到聊天记录
	 */
	const userMsgObj = createMessageObject("user", userMessage);
	// 将用户消息渲染到页面上
	renderMessage(userMsgObj, chatHistoryPanel);
	// 将消息发送到后端 API，并根据是否勾选“包含历史”传递相应参数
	await loadConversationFromAPI(chatHistoryPanel);
};

/**
 * 从API加载对话内容
 *
 * @param {HTMLElement} container - 消息容器元素
 *
 * @param {string|undefined} promptMessage - 自定义提示消息
 *
 * @param {function|undefined} otherHandleModel - 其他的处理器模型
 */
async function loadConversationFromAPI(container, promptMessage, otherHandleModel) {
	/**
	 * 创建一个空内容的助手消息对象，并将其添加到聊天记录中
	 *
	 * 此操作是为了提前占位，后续会逐步填充助手的回复内容
	 */
	const assistantMsgObj = createMessageObject("assistant", "");
	/**
	 * 创建消息元素并将其渲染到页面上
	 *
	 * 这样用户可以看到助手已经开始准备回复
	 */
	let messageElement = await createMessageElement(container, assistantMsgObj);
	// 尝试执行与后端API的交互操作
	try {
		/**
		 * 构建消息数组
		 */
		let messages = await createMessages(promptMessage);
		/**
		 * 默认处理的处理器模型
		 *
		 * @returns {Promise<Response>} - 响应对象
		 */
		async function defaultHandleModel() {
			return contactReasoningModel(reasoningEndpointUrl, reasoningEndpointKey, reasoningModelDropdown, messages, true, true)
		};
		/**
		 * 向处理器模型发送请求并等待响应
		 */
		const response = otherHandleModel ? await otherHandleModel() : await defaultHandleModel();
		// 如果未能获得期望中的响应，则抛出错误
		if (!response.ok) throw new Error(`API返回错误: ${response.status} ${response.statusText}`);
		/**
		 * 获取AI消息内容元素
		 */
		const contentElement = messageElement.querySelector(".markdown-content");
		/**
		 * 创建消息内容元素并渲染
		 */
		const reader = response.body.getReader();
		/**
		 * 创建文本解码器
		 */
		const decoder = new TextDecoder();
		/**
		 * 创建用于保存AI消息的变量
		 */
		let assistantMessage = "";
		// 循环处理流式返回的文本块
		while (true) {
			// 自动处理滚动行为
			autoScrollToBottom(container);
			// 读取数据块
			const { value, done } = await reader.read();
			// 如果传输完成，跳出循环
			if (done) break;
			/**
			 * 解码数据块
			 */
			const chunk = decoder.decode(value);
			/**
			 * 分割成行并过滤空行
			 */
			const lines = chunk.split("\n").filter((line) => line.trim() !== "");
			// 遍历每一行数据
			for (const line of lines) {
				// 检查数据块是否包含有效数据
				if (!line.startsWith("data: ")) continue;
				/**
				 * 获取数据块中的有效数据
				 */
				const data = line.replace("data: ", "");
				// 如果收到结束信号，退出循环
				if (data === "[DONE]") break;
				// 尝试解析流式输出的数据
				try {
					/**
					 * 解析JSON数据
					 */
					const jsonData = JSON.parse(data);
					// 检查数据块是否包含有效数据
					if (!jsonData.choices || jsonData.choices.length === 0 || !jsonData.choices[0].delta.content) continue;
					// 更新推理模型消息内容
					assistantMessage += jsonData.choices[0].delta.content;
					// 在单独的波浪线字符（即前后没有波浪线或空白字符）两侧添加空格，以确保格式一致性
					assistantMessage = assistantMessage.replace(/(?<![~\s])~(?![~\s])/g, ' ~ ');
					// 更新消息内容前保存当前状态
					assistantMsgObj.content = assistantMessage;
					// 处理内容更新，对内容中的思考标签进行处理
					contentElement.innerHTML = processThinkTags(assistantMessage);
					// 为think区块添加折叠功能
					contentElement.querySelectorAll(".toggle_think_button").forEach(bindFoldingButton);
				}
				catch (error) {
					// 捕获异常并显示错误信息
					showSystemMessage(`${error.name} | ${error.message} | ${error.stack}`, "error");
				}
			};
			// 添加代码高亮
			contentElement.querySelectorAll('pre code').forEach(block => hljs.highlightElement(block));
			// 自动渲染页面中的公式（使用$...$或\(...\)语法）
			renderMathInElement(contentElement,
				{
					// 定义公式的分隔符，用于识别不同格式的数学公式
					delimiters: [
						{ left: '$$', right: '$$', display: true }, // 双美元符号表示块级公式
						{ left: '$', right: '$', display: false }, // 单美元符号表示行内公式
						{ left: '\\(', right: '\\)', display: false }, // \( 和 \) 表示行内公式
						{ left: '\\[', right: '\\]', display: true } // \[ 和 \] 表示块级公式
					],
					// 遇到错误时不抛出异常
					throwOnError: false
				}
			);
		};
		/**
		 * 检测情绪标签
		 */
		const emotion = handleEmotionTags(assistantMessage);
		// 如果启用了自动播放功能，播放语音
		if (autoPlaySpeech) playSpeechModel();
		// 处理情绪标签，根据检测结果设置虚拟主播状态
		if (emotion) setStateWithTimeout(emotion);
		// 如果没有情绪标签，则进入说话模式
		else setStateWithTimeout(EmotionalState.SPEAKING);
		// 执行聊天结束事件
		await handleChatEndEvent(assistantMessage, contentElement);
	}
	catch (error) {
		// 添加错误消息到聊天记录
		if (error.name === "AbortError") return;
		// 捕获异常并显示错误信息
		showSystemMessage(`${error.name} | ${error.message} | ${error.stack}`, "error");
		// 渲染错误消息到聊天记录
		tracelessRenderMessage(`抱歉，请求处理时出错: ${error.message}`, container);
	}
	finally {
		// 移除停止生成按钮
		messageElement.querySelector('.stop_generation_button')?.remove();
		// 重新启用输入按钮，允许用户继续发送消息
		disabledInputButton(false);
		// 清理中止控制器
		abortController = null;
	}
};